package main

import (
	"encoding/json"
	"fmt"
	"net"
	"src/lib"
)
// 接收数据
type Msg struct {
	K string `json:"key"`
	V string `json:"value"`
	T string `json:"type"`
}

// 返回数据
type Result struct {
	Code int `json:"code"`
	Data interface{} `json:"data"`
	Status bool `json:"status"`
}

// 队列信息
var mqInfoMap = make(map[string][]string)
// 注册多个消息，类似kafka的topic
var mqArr = []string{"mq_test1", "mq_test2"}

func initData()  {
	// 初始化队列信息
	for i :=0; i < len(mqArr); i++  {
		var arrStr = []string{}
		mqInfoMap[mqArr[i]] = arrStr
	}
}



func main() {
	// 服务端端口
	service := lib.Port
	// 绑定
	tcpAddr, err := net.ResolveTCPAddr("tcp", service)
	lib.CheckError(err)
	// 监听
	listener, err := net.ListenTCP("tcp", tcpAddr)
	lib.CheckError(err)
	// 初始化数据
	initData()
	fmt.Println(mqInfoMap)
	for {
		// 接受
		conn, err := listener.Accept()
		if err != nil {
			continue
		}
		// 创建 Goroutine
		go handleClient(conn)
	}
}
func handleClient(conn net.Conn) {
	// 逆序调用 Close() 保证连接能正常关闭
	defer conn.Close()
	var buf [512]byte
	for {
		// 接收数据
		n, err := conn.Read(buf[0:])
		if err != nil {
			return
		}
		rAddr := conn.RemoteAddr()
		msg := string(buf[0:n])
		fmt.Println("Receive from client", rAddr.String(), msg)
		var m Msg
		err = json.Unmarshal([]byte(msg), &m)
		if(err != nil || m == Msg{}){
			conn.Write([]byte("1"))
			return
		}

		if m.T == "c"{
			handleConsumer(conn, m)
		}else {
			handleProduct(conn, m)
		}
	}
}

func handleConsumer(conn net.Conn, m Msg) {
	var result = Result{}
	arr := mqInfoMap[m.K]
	if len(arr) > 0 {
		arr = append(arr[:0],arr[0+1:]... )
		mqInfoMap[m.K] = arr
		conn.Write([]byte("0"))
		result.Data = 0
		result.Status = true
		jsonByte, _ := json.Marshal(result)
		conn.Write(jsonByte)
		return
	}
	// 没有可以消费的数据
	result.Data = 1
	result.Status = true
	jsonByte, _ := json.Marshal(result)
	conn.Write(jsonByte)
}

func handleProduct(conn net.Conn, m Msg) {
	var result = Result{}
	arr := mqInfoMap[m.K]
	arr = append(arr, m.V)
	mqInfoMap[m.K] = arr

	result.Data = 0
	result.Status = true
	jsonByte, _ := json.Marshal(result)
	conn.Write(jsonByte)
}


